package com.zx1316.javasimpledoudizhu.client;

import com.zx1316.javasimpledoudizhu.Main;
import com.zx1316.javasimpledoudizhu.client.ui.ClientController;
import com.zx1316.javasimpledoudizhu.client.ui.UIHelper;
import com.zx1316.javasimpledoudizhu.misc.Card;
import javafx.application.Platform;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Comparator;
import java.util.Vector;

public class ReceiveThread extends Thread {
    private final ClientController controller;
    private final Socket socket;
    private final String name;
    private final Judge judge;
    private final UIHelper uiHelper;
    private Vector<Card> cardsList = new Vector<>();
    private Vector<Card> discards = new Vector<>();
    private int gameState = 0;

    public ReceiveThread(ClientController controller, Socket socket, String name, Judge judge, UIHelper uiHelper) throws IOException {
        this.controller = controller;
        this.socket = socket;
        this.name = name;
        this.judge = judge;
        this.uiHelper = uiHelper;
    }

    @Override
    public void run() {
        int passCounter = 0;
        int maxCall = 0;
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter writer = new PrintWriter(socket.getOutputStream());
            while (!socket.isClosed()) {
                String message = reader.readLine();
                if (message == null) {
                    handleServerClose("[服务器]已断开连接！");
                    return;
                }
                String[] split = message.split("@");
                if ("NAME".equals(split[0])) {
                    int pos;
                    if (name.equals(split[1])) {
                        pos = 0;
                    } else if (name.equals(split[2])) {
                        pos = 1;
                    } else {
                        pos = 2;
                    }
                    Platform.runLater(() -> {
                        controller.name1.setText(split[pos + 1]);
                        controller.name2.setText(split[(pos + 1) % 3 + 1]);
                        if (" ".equals(controller.name2.getText())) {
                            controller.info2.setText("");
                        }
                        controller.name3.setText(split[(pos + 2) % 3 + 1]);
                        if (" ".equals(controller.name3.getText())) {
                            controller.info3.setText("");
                        }
                    });
                } else if ("KICK".equals(split[0])) {
                    handleServerClose("[服务器]您已被踢出服务器！");
                    writer.println("CLOSE");
                    writer.flush();
                    socket.close();
                    return;
                } else if ("CLOSE".equals(split[0])) {
                    handleServerClose("[服务器]已断开连接！");
                    return;
                } else if ("CHAT".equals(split[0])) {
                    StringBuilder sb = new StringBuilder("[");
                    sb.append(split[split.length - 1]);
                    sb.append("]");
                    sb.append(split[1]);
                    for (int i = 2; i < split.length - 1; i++) {
                        sb.append("@");
                        sb.append(split[i]);
                    }
                    sb.append('\n');
                    Platform.runLater(() -> controller.chatHistory.appendText(sb.toString()));
                } else if ("START".equals(split[0])) {
                    judge.clear();
                    discards = new Vector<>();
                    maxCall = 0;
                    Platform.runLater(() -> {
                        controller.rounds.setText(split[1] + "/" + controller.rounds.getText().split("/")[1]);
                        uiHelper.clearDiscards(0);
                        uiHelper.clearDiscards(1);
                        uiHelper.clearDiscards(2);
                        uiHelper.updateScore();
                        uiHelper.resetRemainings();
                        uiHelper.clearLandlords();
                        uiHelper.clearDoubles();
                    });
                } else if ("CARD".equals(split[0])) {
                    Platform.runLater(() -> {
                        uiHelper.clearInfos();
                        controller.points.setText("");
                        controller.landlordCard.setText("");
                        uiHelper.resetTips();
                    });
                    cardsList = new Vector<>();
                    for (int i = 1; i < 18; i++) {
                        Card card = new Card(split[i]);
                        Platform.runLater(() -> uiHelper.tipsDec(card));
                        cardsList.add(card);
                    }
                    uiHelper.showHands(cardsList);
                } else if ("DELETE".equals(split[0])) {
                    Platform.runLater(() -> {
                        if (split[1].equals(controller.name2.getText())) {
                            controller.offline2.setVisible(true);
                        } else {
                            controller.offline3.setVisible(true);
                        }
                    });
                } else if ("ADD".equals(split[0])) {
                    Platform.runLater(() -> {
                        if (split[1].equals(controller.name2.getText())) {
                            controller.offline2.setVisible(false);
                        } else {
                            controller.offline3.setVisible(false);
                        }
                    });
                } else if ("READY".equals(split[0])) {
                    Platform.runLater(() -> uiHelper.setInfo(uiHelper.getPosFromName(split[1]), "准备"));
                } else if ("CALL".equals(split[0])) {
                    String s = switch (split[1]) {
                        case "0" -> "不叫";
                        case "1" -> "1分";
                        case "2" -> "2分";
                        default -> "3分";
                    };
                    if (Integer.parseInt(split[1]) > maxCall) {
                        maxCall = Integer.parseInt(split[1]);
                    }
                    Platform.runLater(() -> uiHelper.setInfo(uiHelper.getPosFromName(split[2]), s));
                } else if ("DOUBLE".equals(split[0])) {
                    if ("true".equals(split[1])) {
                        Platform.runLater(() -> uiHelper.setDouble(uiHelper.getPosFromName(split[2])));
                    }
                } else if ("LANDLORD".equals(split[0])) {
                    if (split[5].equals(name)) {
                        for (int i = 2; i < 5; i++) {
                            Card card = new Card(split[i]);
                            cardsList.add(card);
                            Platform.runLater(() -> uiHelper.tipsDec(card));
                        }
                        cardsList.sort(Comparator.reverseOrder());
                    }
                    char[] chars = (split[2] + split[3] + split[4]).toCharArray();
                    int i = 0;
                    while (i < chars.length) {
                        if (chars[i] == '0') {
                            i++;
                        } else {
                            switch (chars[i]) {
                                case 'D' -> chars[i] = '♦';
                                case 'C' -> chars[i] = '♣';
                                case 'H' -> chars[i] = '♥';
                                case 'S' -> chars[i] = '♠';
                                default -> {
                                    if (chars[i + 1] == 'B') {
                                        chars[i] = '大';
                                    } else {
                                        chars[i] = '小';
                                    }
                                    chars[i + 1] = '王';
                                }
                            }
                            i += 2;
                        }
                    }
                    Platform.runLater(() -> {
                        uiHelper.clearInfos();
                        controller.points.setText(split[1]);
                        controller.landlordCard.setText(new String(chars));
                        uiHelper.setLandlord(uiHelper.getPosFromName(split[5]));
                        if (split[5].equals(name)) {
                            try {
                                uiHelper.showHands(cardsList);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    });
                } else if ("CALL?".equals(split[0])) {
                    playRemind();
                    gameState = 1;
                    int finalMaxCall = maxCall;
                    Platform.runLater(() -> {
                        controller.confirm.setVisible(false);
                        controller.pass.setText("不叫");
                        controller.pass.setDisable(false);
                        controller.call1.setDisable(false);
                        controller.call2.setDisable(false);
                        if (finalMaxCall == 1) {
                            controller.call1.setDisable(true);
                        } else if (finalMaxCall == 2) {
                            controller.call1.setDisable(true);
                            controller.call2.setDisable(true);
                        }
                        controller.call1.setVisible(true);
                        controller.call2.setVisible(true);
                        controller.call3.setVisible(true);
                        controller.pass.setVisible(true);
                    });
                } else if ("DOUBLE?".equals(split[0])) {
                    playRemind();
                    gameState = 2;
                    Platform.runLater(() -> {
                        controller.pass.setText("不加倍");
                        controller.confirm.setText("加倍");
                        controller.pass.setDisable(false);
                        controller.pass.setVisible(true);
                        controller.confirm.setVisible(true);
                    });
                } else if ("PLAY".equals(split[0])) {
                    playRemind();
                    gameState = 3;
                    Platform.runLater(() -> {
                        controller.pass.setText("过牌");
                        controller.pass.setDisable(discards.isEmpty());
                        controller.pass.setVisible(true);
                        controller.confirm.setText("出牌");
                        controller.confirm.setVisible(true);
                    });
                } else if ("DISCARD".equals(split[0])) {
                    passCounter = 0;
                    if (name.equals(split[split.length - 1])) {
                        for (int i = 1; i < split.length - 1; i++) {
                            cardsList.remove(new Card(split[i]));
                        }
                    }
                    discards = new Vector<>();
                    for (int i = 1; i < split.length - 1; i++) {
                        Card card = new Card(split[i]);
                        if (!name.equals(split[split.length - 1])) {
                            Platform.runLater(() -> uiHelper.tipsDec(card));
                        }
                        discards.add(new Card(split[i]));
                    }
                    judge.judgeOther(discards);
                    Platform.runLater(() -> {
                        try {
                            uiHelper.showDiscards(discards, uiHelper.getPosFromName(split[split.length - 1]));
                            if (uiHelper.getPosFromName(split[split.length - 1]) == 0) {
                                uiHelper.showHands(cardsList);
                            }
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });
                } else if ("REMAINING".equals(split[0])) {
                    if (!split[split.length - 1].equals(name)) {
                        Platform.runLater(() -> {
                            try {
                                if (controller.name2.getText().equals(split[split.length - 1])) {
                                    uiHelper.showDiscards(split, 1);
                                } else {
                                    uiHelper.showDiscards(split, 2);
                                }
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        });
                    }
                } else if ("PASS".equals(split[0])) {
                    passCounter++;
                    Platform.runLater(() -> {
                        uiHelper.clearDiscards(uiHelper.getPosFromName(split[1]));
                        uiHelper.setInfo(uiHelper.getPosFromName(split[1]), "过");
                    });
                    if (passCounter == 2) {
                        judge.clear();
                        passCounter = 0;
                        discards = new Vector<>();
                        Platform.runLater(() -> {
                            uiHelper.clearInfos();
                            uiHelper.clearDiscards(0);
                            uiHelper.clearDiscards(1);
                            uiHelper.clearDiscards(2);
                        });
                    }
                } else if ("BOMB".equals(split[0])) {
                    if ("true".equals(split[1])) {
                        MediaPlayer soundPlayer = new MediaPlayer(new Media(Main.class.getResource("explode.mp3").toString()));
                        soundPlayer.play();
                    }
                    Platform.runLater(() -> controller.points.setText(String.valueOf(Integer.parseInt(controller.points.getText()) * 2)));
                } else if ("SCORE".equals(split[0])) {
                    gameState = 0;
                    Platform.runLater(() -> {
                        if (split.length == 7) {
                            uiHelper.showScoreChange(uiHelper.getPosFromName(split[1]), split[2]);
                            uiHelper.showScoreChange(uiHelper.getPosFromName(split[3]), split[4]);
                            uiHelper.showScoreChange(uiHelper.getPosFromName(split[5]), split[6]);
                        } else {
                            controller.rounds.setText((Integer.parseInt(split[7]) - 1) + "/" + controller.rounds.getText().split("/")[1]);
                            uiHelper.setScore(split[2], uiHelper.getPosFromName(split[1]));
                            uiHelper.setScore(split[4], uiHelper.getPosFromName(split[3]));
                            uiHelper.setScore(split[6], uiHelper.getPosFromName(split[5]));
                        }
                        String[] spilt1 = controller.rounds.getText().split("/");
                        if (!spilt1[0].equals(spilt1[1])) {
                            playRemind();
                            controller.confirm.setText("准备");
                            controller.confirm.setVisible(true);
                        }
                    });
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void handleServerClose(String s) {
        controller.stopBGM();
        Platform.runLater(() -> {
            controller.chatHistory.appendText(s);
            controller.connect.setDisable(false);
            controller.disconnect.setDisable(true);
            controller.hostname.setDisable(false);
            controller.port.setDisable(false);
            controller.pwd.setDisable(false);
            controller.name.setDisable(false);
            controller.send.setDisable(true);
            controller.confirm.setVisible(false);
            controller.pass.setVisible(false);
            controller.call1.setVisible(false);
            controller.call2.setVisible(false);
            controller.call3.setVisible(false);
            controller.rounds.setText("");
            controller.landlordCard.setText("");
            controller.points.setText("");
            controller.tips.setVisible(false);
            uiHelper.resetAll();
        });
    }

    public Vector<Card> getCardsList() {
        return cardsList;
    }

    public int getGameState() {
        return gameState;
    }

    private void playRemind() {
        MediaPlayer soundPlayer = new MediaPlayer(new Media(Main.class.getResource("remind.mp3").toString()));
        soundPlayer.play();
    }
}
